package com.sql.api;

import com.sql.bean.DataInfo;
import com.sql.bean.TableInfo;
import com.sql.common.intc.SqlTypeConvert;
import com.sql.common.util.ConnectionFactory;
import com.sql.common.util.NameUtil;

import java.sql.PreparedStatement;
import java.util.*;

public class HtmlRunnerApi {

    private ConnectionFactory connectionFactory;

    private Searcher searcher;

    public HtmlRunnerApi(ConnectionFactory connectionFactory){
        this.connectionFactory = connectionFactory;
        searcher = new Searcher(connectionFactory);
    }

    public void setConnectionFactory(ConnectionFactory connectionFactory){
        this.connectionFactory=connectionFactory;
        searcher.setConnectionFactory(connectionFactory);
    }

    public DataInfo execSql(String sql,Object []params,Map<Integer,SqlTypeConvert> mapTypeConvert) throws Exception{
        if(sql.length()==0){
            return null;
        }
        if(sql.toUpperCase().equals("SHOW TABLES")){
            return showTables();
        }else if(sql.toUpperCase().startsWith("SHOW COLUMNS FROM ")){
            String table = sql.substring("SHOW COLUMNS FROM ".length());
            return showTableInfos(table);
        }else if(sql.trim().toUpperCase().startsWith("SELECT")){
            return showSelectQuery(sql,params,mapTypeConvert);
        }else if(sql.trim().toUpperCase().startsWith("INSERT") ||
                sql.trim().toUpperCase().startsWith("UPDATE") || sql.trim().toUpperCase().startsWith("DELETE")
                || sql.trim().toUpperCase().startsWith("DELETE")
                || sql.trim().toUpperCase().startsWith("CREATE")
                || sql.trim().toUpperCase().startsWith("DROP")
                || sql.trim().toUpperCase().startsWith("ALTER")){
            return showUpdate(sql,params);
        }else if(sql.trim().toUpperCase().equals("COMMIT")){
            connectionFactory.commit();
            return otherExec("提交完成");
        }else if(sql.trim().toUpperCase().equals("ROLLBACK")){
            connectionFactory.rollback();
            return otherExec("回滚完成");
        }else{
            throw new Exception("未知的命令！");
        }
    }

    private DataInfo showTables() throws Exception{
        DataInfo dataInfo = new DataInfo();
        List<String> list = searcher.showTables();
        dataInfo.setInfotype("tableInfo");
        dataInfo.setInfoData(list);
        return dataInfo;
    }

    private DataInfo showTableInfos(String tableName)throws Exception{
        DataInfo dataInfo = new DataInfo();
        List<TableInfo> list = searcher.showTableInfo(tableName);
        dataInfo.setInfotype("columnInfo");
        List<Map<String,String>> result = new LinkedList<>();
        Map<String,String> content;
        for(TableInfo t:list){
            content = new HashMap<>();
            content.put("column",t.getTableColumn());
            content.put("type",t.getColumnType());
            content.put("desc",t.getColumCommon());
            result.add(content);
        }
        dataInfo.setInfoData(result);
        return dataInfo;
    }

    private DataInfo showSelectQuery(String sql,Object[] params,Map<Integer,SqlTypeConvert> mapTypeConvert)throws Exception{
        DataInfo dataInfo = new DataInfo();
        dataInfo.setInfotype("queryInfo");
        List<Map<String,Object>> list = (List<Map<String, Object>>) connectionFactory.getDao().getBySql(Map.class,sql,mapTypeConvert,params);
        List<Map<String,Object>> arr=null;
        if(list!=null && !list.isEmpty()){
            arr = new ArrayList<>(list.size());
            Map<String,Object> result = new HashMap<>(2);
            List<String> columns = new LinkedList<>();
            List<Object> values = new LinkedList<>();
            dataInfo.setInfoData(result);
            result.put("column",columns);
            result.put("value",values);
            for(String str:list.get(0).keySet()){
                columns.add(str);
            }
            Map<String,Object> keyv;
            for(Map<String,Object> e:list){
                keyv = new HashMap<>();
                values.add(e.values());
                for(Map.Entry<String,Object> m:e.entrySet()){
                    keyv.put(NameUtil.toJavaNamed(m.getKey()),m.getValue());
                }
                arr.add(keyv);
            }
        }
        dataInfo.setArr(arr);
        return dataInfo;
    }

    private DataInfo showUpdate(String sql,Object []params)throws Exception{
        DataInfo dataInfo = new DataInfo();
        dataInfo.setInfotype("updateInfo");
        PreparedStatement p = connectionFactory.getDao().getPreparedStatement(sql);
        if(params!=null){
            for(int i=0;i<params.length;i++){
                p.setObject(i+1,params[i]);
            }
        }
        int i=p.executeUpdate();
        dataInfo.setInfoData(i);
        return dataInfo;
    }

    private DataInfo otherExec(String text) throws Exception{
        DataInfo dataInfo = new DataInfo();
        dataInfo.setInfotype("execInfo");
        dataInfo.setInfoData(text);
        return dataInfo;
    }


}
